<?php
/**
 * 小程序登登录
 */
namespace app\facescore\home;
use app\common\controller\Common;
use app\common\model\AdminMember as MemberModel;
use think\helper\Time;
use \think\Session;
use think\Db;

class Login extends Common
{


    public function index()
    {
        /**
         * 3.小程序调用server获取token接口, 传入code, rawData, signature, encryptData.
         */
        $code = input("code", '', 'htmlspecialchars_decode');
        $rawData = input("rawData", '', 'htmlspecialchars_decode');
        $signature = input("signature", '', 'htmlspecialchars_decode');
        $encryptedData = input("encryptedData", '', 'htmlspecialchars_decode');
        $iv = input("iv", '', 'htmlspecialchars_decode');
        $this->url = 'https://api.weixin.qq.com/sns/jscode2session';
        /**
         * 4.server调用微信提供的jsoncode2session接口获取openid, session_key, 调用失败应给予客户端反馈
         * , 微信侧返回错误则可判断为恶意请求, 可以不返回. 微信文档链接
         * 这是一个 HTTP 接口，开发者服务器使用登录凭证 code 获取 session_key 和 openid。其中 session_key 是对用户数据进行加密签名的密钥。
         * 为了自身应用安全，session_key 不应该在网络上传输。
         * 接口地址："https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code"
         */
        $params = [
            'appid' => config('module_facescore.appid'),
            'secret' => config('module_facescore.secret'),
            'js_code' => $code,
            'grant_type' => 'authorization_code'
        ];

        $res = $this->makeRequest($this->url, $params);

        if ($res['code'] !== 200 || !isset($res['result']) || !isset($res['result'])) {
            return json(ret_message('requestTokenFailed'));
        }
        $reqData = json_decode($res['result'], true);
        if (!isset($reqData['session_key'])) {
            return json($this->ret_message('requestTokenFailed'));
        }
        $sessionKey = $reqData['session_key'];

        /**
         * 5.server计算signature, 并与小程序传入的signature比较, 校验signature的合法性, 不匹配则返回signature不匹配的错误. 不匹配的场景可判断为恶意请求, 可以不返回.
         * 通过调用接口（如 wx.getUserInfo）获取敏感数据时，接口会同时返回 rawData、signature，其中 signature = sha1( rawData + session_key )
         *
         * 将 signature、rawData、以及用户登录态发送给开发者服务器，开发者在数据库中找到该用户对应的 session-key
         * ，使用相同的算法计算出签名 signature2 ，比对 signature 与 signature2 即可校验数据的可信度。
         */
        $signature2 = sha1($rawData . $sessionKey);

        if ($signature2 !== $signature) return ret_message("signNotMatch");

        /**
         *
         * 6.使用第4步返回的session_key解密encryptData, 将解得的信息与rawData中信息进行比较, 需要完全匹配,
         * 解得的信息中也包括openid, 也需要与第4步返回的openid匹配. 解密失败或不匹配应该返回客户相应错误.
         * （使用官方提供的方法即可）
         */

        $pc = new WXBizDataCrypt(config('module_facescore.appid'), $sessionKey);

        $errCode = $pc->decryptData($encryptedData, $iv, $data );

        if ($errCode !== 0) {
            return json($this->ret_message("encryptDataNotMatch"));
        }


        //拿到用户登录数据
        $data = json_decode($data, true);
        // $data['openId'] = 'o9dTx5Al0mORKodi3znaVS6W0Klg';
        $userData = array(
            "username" => $data['nickName'],
            "nick" => $data['nickName'],
            "avatar" => $data['avatarUrl'],
            "openid" => $data['openId'],
            "sex" => $data['gender']
        );
        //检查有没有注册过
        $row = MemberModel::where("openid",$data['openId'])->find();


        if(!$row) {
            $is_first = 1;
            if(MemberModel::create($userData)){ 
                $row = MemberModel::where("openid",$data['openId'])->find();
            }
        }else{
              $is_first = 0; //是否第一次注册 0 不是 1 是 
        }
        //微信注册信息有变动修改信息
//        if($data['avatarUrl'] != $row['avatar'] || $data['nickName'] != $row['nick'] || $data['gender'] != $row['sex']) {
//            Db::name('admin_member')->where(['openid' => $data['openId']])->update($userData);
//        }
        $data['nickName'] = $row['nick'];
        $data['avatarUrl'] = $row['avatar'];
        $data['gender'] = $row['sex'];
        $data['uid'] = $row['id'];
        $data['qianming'] = $row['qianming'] == null ? '' : $row['qianming'];
        $data['birthday'] = $row['birthday'];
        $data['money'] = $row['money'];
        $data['mobile'] = $row['mobile'];
        $data['home_page_img'] = $row['home_page_img'] == null ? '' : $row['home_page_img'];
        $data['invi_person'] = $row['invi_person']; //邀请人数
        $data['invi_mag'] = $row['invi_mag']; //邀请或得的mag
        $data['is_first'] = $is_first;
        $data['invi_uid'] = $row['invi_uid']  == null ? '' : $row['invi_uid']; //邀请人uid

        return json($data);
    }
    public function test()
    {
        $data = [1,2];
        $this->assign('data', $data);
        echo 'test方法';
        //return $this->fetch();
    }

    function ret_message($message = "") {
        if ($message == "") return ['result'=>0, 'message'=>''];
        $ret = lang($message);

        if (count($ret) != 2) {
            return ['result'=>-1,'message'=>'未知错误'];
        }
        return array(
            'result'  => $ret[0],
            'message' => $ret[1]
        );
    }

    /**
     * 发起http请求
     * @param string $url 访问路径
     * @param array $params 参数，该数组多于1个，表示为POST
     * @param int $expire 请求超时时间
     * @param array $extend 请求伪造包头参数
     * @param string $hostIp HOST的地址
     * @return array    返回的为一个请求状态，一个内容
     */
    function makeRequest($url, $params = array(), $expire = 0, $extend = array(), $hostIp = '')
    {
        if (empty($url)) {
            return array('code' => '100');
        }

        $_curl = curl_init();
        $_header = array(
            'Accept-Language: zh-CN',
            'Connection: Keep-Alive',
            'Cache-Control: no-cache'
        );
        // 方便直接访问要设置host的地址
        if (!empty($hostIp)) {
            $urlInfo = parse_url($url);
            if (empty($urlInfo['host'])) {
                $urlInfo['host'] = substr(DOMAIN, 7, -1);
                $url = "http://{$hostIp}{$url}";
            } else {
                $url = str_replace($urlInfo['host'], $hostIp, $url);
            }
            $_header[] = "Host: {$urlInfo['host']}";
        }

        // 只要第二个参数传了值之后，就是POST的
        if (!empty($params)) {
            curl_setopt($_curl, CURLOPT_POSTFIELDS, http_build_query($params));
            curl_setopt($_curl, CURLOPT_POST, true);
        }

        if (substr($url, 0, 8) == 'https://') {
            curl_setopt($_curl, CURLOPT_SSL_VERIFYPEER, FALSE);
            curl_setopt($_curl, CURLOPT_SSL_VERIFYHOST, FALSE);
        }
        curl_setopt($_curl, CURLOPT_URL, $url);
        curl_setopt($_curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($_curl, CURLOPT_USERAGENT, 'API PHP CURL');
        curl_setopt($_curl, CURLOPT_HTTPHEADER, $_header);

        if ($expire > 0) {
            curl_setopt($_curl, CURLOPT_TIMEOUT, $expire); // 处理超时时间
            curl_setopt($_curl, CURLOPT_CONNECTTIMEOUT, $expire); // 建立连接超时时间
        }

        // 额外的配置
        if (!empty($extend)) {
            curl_setopt_array($_curl, $extend);
        }

        $result['result'] = curl_exec($_curl);
        $result['code'] = curl_getinfo($_curl, CURLINFO_HTTP_CODE);
        $result['info'] = curl_getinfo($_curl);
        if ($result['result'] === false) {
            $result['result'] = curl_error($_curl);
            $result['code'] = -curl_errno($_curl);
        }

        curl_close($_curl);
        return $result;
    }

    /**
     * 读取/dev/urandom获取随机数
     * @param $len
     * @return mixed|string
     */
    function randomFromDev($len) {
        $fp = @fopen('/dev/urandom','rb');
        $result = '';
        if ($fp !== FALSE) {
            $result .= @fread($fp, $len);
            @fclose($fp);
        }
        else
        {
            trigger_error('Can not open /dev/urandom.');
        }
        // convert from binary to string
        $result = base64_encode($result);
        // remove none url chars
        $result = strtr($result, '+/', '-_');

        return substr($result, 0, $len);
    }

    /**
     * 发送短信验证码
     */
    function sendCode(){
        if(!checkLogin()){
            return json(['msg' => '没有登录']);
        }

        //校验一个小时之内是否发了超过十次

       $count =  Db::name('facescore_code')->where(['mobile' => input('mobile')])->whereTime('create_time','-1 hours')->count();

        if($count >= 10) {
            return json(['msg' => '手机号码验证次数过多，请稍后重试']);
        }
        $rand = rand(1000,9999);
        $content = "【麦颜值】验证码为".$rand."，您正在登陆麦颜值，请在5分钟内完成验证，如非本人操作，请忽略本短信";/* 短信内容请以商务约定的为准，如果已经在通道端绑定了签名，则无需在这里添加签名 */
        $timestamp = date("YmdHis");
        $appId = 'EUCP-EMY-SMS1-345ZG';
        $secretKey = '2971E448916A32B4';
        $sign = signmd5($appId,$secretKey,$timestamp);
        // 如果您的系统环境不是UTF-8，需要转码到UTF-8。如下：从gb2312转到了UTF-8
        // $content = mb_convert_encoding( $content,"UTF-8","gb2312");
        // 另外，如果包含特殊字符，需要对内容进行urlencode
        $data = array(
            "appId" => $appId,
            "timestamp" => $timestamp,
            "sign" => $sign,
            "mobiles" => input('mobile'),
            "content" =>  $content,
            "customSmsId" => "10001",
            "timerTime" => "",
            "extendedCode" => ""
        );
        $url = 'http://bjmtn.b2m.cn/simpleinter/sendSMS';
        $resobj = http_request($url, $data);
        $resobj = json_decode($resobj);



        //发送验证码成功
        if($resobj->code == 'SUCCESS') {
            $data = [
                'uid' => input('uid'),
                'code' => $rand,
                'create_time' => time(),
                'mobile' => input('mobile')
            ];
            Db::name('facescore_code')->insert($data);
            return json(['code_id' => Db::name('facescore_code')->getLastInsID()]);
        }else{
            return json(['msg' => '验证码发送失败']);
        }
    }

    /**
     * 验证短信验证码
     */
    function  checkCode(){
        if(!checkLogin()){
            return json(['msg' => '没有登录']);
        }
        $data_list =  Db::name('facescore_code')->where(['uid' => input('uid'),'mobile' => input('mobile'),'id' => input('code_id'),'code' => input('code')])->find();
        if(sizeof($data_list) == 0) {
            return json(['msg' => '验证码错误','code' => -1]);
        }else{
            if($data_list['create_time'] < time() - 300) {
                return json(['msg' => '验证码过期，请重新获取','code' => -1]);
            }else{
                $update_data = [];
                $update_data['mobile'] = input('mobile');
                //存在上级邀请人
                if(input('supe_uid') != null) {
                    $update_data['supe_uid'] = input('supe_uid');
                    
                    //上级邀请人存在 给邀请人和注册人发放麦粒
                    $supe_user =  Db::name('admin_member')->where(['id' => input('supe_uid')])->find();
                     //邀请人增加一条流水记录
                    $flow_data = [
                        'time' => date('Y-m-d H:i:s',time()),
                        'name' => '邀请奖励',
                        'money' => config('module_facescore.invi_award'),
                        'uid' => input('supe_uid'), //打赏人的uid
                        'type' => 'mag'
                    ];
                    db::name('facescore_flow')->insert($flow_data);

                     //更新邀请人推荐人数 和 累计获得mag
                     db::name('admin_member')->where('id',input('supe_uid'))->update(['invi_person'=>Db::raw('invi_person+1'),'invi_mag'=>Db::raw('invi_mag+'.config('module_facescore.invi_award'))]);

                    //注册人增加一条流水记录
                    $flow_data = [
                        'time' => date('Y-m-d H:i:s',time()),
                        'name' => '注册奖励',
                        'money' => config('module_facescore.new_award'),
                        'uid' => input('uid'), 
                        'type' => 'mag'
                    ];
                    db::name('facescore_flow')->insert($flow_data);

                    //给邀请人发放mag
                    $txNo = 'facescore_awardToInvi_'.date('ymdHis').'_'.rand(1000,9999);
                    $post_data = [
                        "txNo" => $txNo,
                        "fromUserCode" => "facescoreOfficial",//麦颜值官方收款账户 标识
                        "toUserCode" => $supe_user['mobile'], //邀请人手机号  
                        "amt" => (double)config('module_facescore.invi_award'),  //后台设置的
                        "describe" => '麦颜值给邀请人发放mag',
                        "message" => ''
                    ];
                    $res = http_request(config('module_facescore.mag_api_url') . '/payment/transfer/MAG',$post_data);
                    $res = json_decode($res,true);
                    if($res['status'] != '0000') {
                        throw new \think\exception\HttpException(404, '异常消息', null);
                    }



                     //给新用户发放mag
                    $txNo = 'facescore_awardToNewuser_'.date('ymdHis').'_'.rand(1000,9999);
                    $post_data = [
                        "txNo" => $txNo,
                        "fromUserCode" => "facescoreOfficial",//麦颜值官方收款账户 标识
                        "toUserCode" => input('mobile'), //新用户手机号  
                        "amt" => (double)config('module_facescore.new_award'),  //后台设置的
                        "describe" => '麦颜值给新用户发放mag',
                        "message" => ''
                    ];
                    $res = http_request(config('module_facescore.mag_api_url') . '/payment/transfer/MAG',$post_data);
                    $res = json_decode($res,true);
                    if($res['status'] != '0000') {
                        throw new \think\exception\HttpException(404, '异常消息', null);
                    }

                }
                //更新注册人的信息
                Db::name('admin_member')->where(['id' => input('uid')])->update($update_data);
                return json(['code' => 1]);
            }
        }
    }

    //检验手机号是否被绑定过
    function checkMobile(){
        if(!checkLogin()){
            return json(['msg' => '没有登录']);
        }
        $count = Db::name('admin_member')->where(['mobile' => input('mobile')])->count();
        if($count == 0) {
            return json(['code' => 1,'msg' => '手机号可用']);
        }else{
            return json(['code' => -1,'msg' => '手机号被占用','count' => $count]);
        }
    }

  
}